// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

#ifndef BASE64_H_
#define BASE64_H_

#include <stdint.h>
#include <stddef.h>
#include "status/rot_status.h"


/**
 * The output length for base64 encoding, including a NULL terminator, based on the input length of
 * the data.
 */
#define	BASE64_LENGTH(x)	((((4 * (x) / 3) + 3) & ~0x3) + 1)


/**
 * A platform-independent API for base64 encoding.  Base64 engine instances are not guaranteed to be
 * thread-safe.
 */
struct base64_engine {
	/**
	 * Encode a data buffer as base64.
	 *
	 * @param engine The base64 engine to use for encoding.
	 * @param data The data to encode.
	 * @param length The length of the data.
	 * @param encoded Output buffer for the encoded data.  The output will be NULL terminated.
	 * @param enc_length The size of the output buffer.  This must be at least BASE64_LENGTH bytes.
	 *
	 * @return 0 if the data was encoded successfully or an error code.
	 */
	int (*encode) (struct base64_engine *engine, const uint8_t *data, size_t length,
		uint8_t *encoded, size_t enc_length);
};


#define	BASE64_ENGINE_ERROR(code)		ROT_ERROR (ROT_MODULE_BASE64_ENGINE, code)

/**
 * Error codes that can be generated by a base64 engine.
 */
enum {
	BASE64_ENGINE_INVALID_ARGUMENT = BASE64_ENGINE_ERROR (0x00),	/**< Input parameter is null or not valid. */
	BASE64_ENGINE_NO_MEMORY = BASE64_ENGINE_ERROR (0x01),			/**< Memory allocation failed. */
	BASE64_ENGINE_ENCODE_FAILED = BASE64_ENGINE_ERROR (0x02),		/**< The data was not encoded. */
	BASE64_ENGINE_ENC_BUFFER_TOO_SMALL = BASE64_ENGINE_ERROR (0x03),/**< There is not enough space for the base64 encoded data. */
	BASE64_ENGINE_HW_NOT_INIT = BASE64_ENGINE_ERROR (0x04),			/**< The base64 hardware has not been initialized. */
};


#endif /* BASE64_H_ */
